(use ./common ./netfunc)

(defn make-queue ( &opt fx)
   (var token-nth @{})
  (var nth-token @{})
  (var token-val @{})
  (var in-queue? (. get token-nth))
  (var call-queue nil) #Initialize.
  (defn- can-queue? (token)
      (not (get token-nth token)))
  (defn- add-to-queue (token)
    (def len (length token-nth))
    (set (nth-token len) token)
    (set (token-nth token) len)
     len)
  (defn- set-in-queue (token val)
    (if (not (in-queue? token)) (add-to-queue token))
    (set (token-val token) val)
    token)
  (defn- update-queue-with (&opt token val & _) #You'd ideally expose this one.
    (default token (os/cryptorand 32)) #TODO Hash the address of the player instead to discourage multiple sessions?
    (default val nil)
    (if (can-queue? token)
      (set-in-queue token val)
      :CannotQueue)) #Error
  (defn- reset-queue ()
    (map table/clear [token-nth nth-token token-val]))
  (if fx (set call-queue (fn call-queue (& args)
           (map (. fx ;args) token-val)
           (reset-queue))))
    {:queue-call call-queue :reset-queue reset-queue
     :queue-update update-queue-with :set-queue set-in-queue
     :add-queue add-to-queue :get-queue in-queue?
    :queue [token-val token-nth nth-token] })

(defn queue-call (fx queue)
  (map fx ((queue :queue) 0)))
